#include "MulticastClass.h"

MulticastClass::MulticastClass()
{
	port = 54321;
	
	l = new QLabel();
	l->setText("<b>Log:</b><br />");
	
	w = new QWidget();
	w->resize(505, 332);
	
	QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(l);
    w->setLayout(layout);
	
	w->show();
	
	

	sock.bind(port, QUdpSocket::ShareAddress);
	int sendingFileDescriptor = sock.socketDescriptor();
	
	if(sendingFileDescriptor != -1)
	{

		struct sockaddr_in sendAddr;
		memset(&sendAddr, 0, sizeof(sendAddr));
		sendAddr.sin_family = AF_INET;
		sendAddr.sin_addr.s_addr = inet_addr("238.38.38.38"); //Chosen Broadcast address!!
		sendAddr.sin_port = htons(port);

		ip_mreq mreq;
		memset(&mreq, 0, sizeof(ip_mreq));
		mreq.imr_multiaddr.s_addr = inet_addr("238.38.38.38"); // group addr
		mreq.imr_interface.s_addr = htons(INADDR_ANY); // use default

		//Make this a member of the Multicast Group
		if(setsockopt(sendingFileDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)) < 0)
		{
			l->setText(l->text() + "set opt error: MEMBERSHIP<br/>");

		}
		
		// set TTL (Time To Live)
		unsigned int ttl = 238; // restricted to 38 hops
		
		if (setsockopt(sendingFileDescriptor, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl) ) < 0)
		{
			l->setText(l->text() + "set opt error: TTL<br/>");

		}
		
		int TivaSocketId = socket(AF_INET, SOCK_DGRAM, 0);
 		struct sockaddr_in TivaSinStruct;
		TivaSinStruct.sin_family = AF_INET;
		TivaSinStruct.sin_port = htons(port);
		TivaSinStruct.sin_addr.s_addr = inet_addr("238.38.38.38");
		
		qDebug() << "TTL:" << setsockopt(TivaSocketId, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl));
		
		ip_mreq TivaMreq;
		
		memset(&TivaMreq,0,sizeof(ip_mreq));
		TivaMreq.imr_multiaddr.s_addr = inet_addr("238.38.38.38"); // group addr
		TivaMreq.imr_interface.s_addr = htons(INADDR_ANY); // use default

		qDebug() << "MEMBERSHIP:" << setsockopt(TivaSocketId, IPPROTO_IP, IP_ADD_MEMBERSHIP,	(const char *)&TivaMreq,sizeof(TivaMreq));
		
		/* try to send in multicast */
		QString OMsg("i'm a fucker!!!");
		
		sendto(TivaSocketId, OMsg.toAscii(), OMsg.toAscii().size(), 0, (struct sockaddr *)&TivaSinStruct, sizeof(TivaSinStruct));
		l->setText(l->text() + "Sended datagram<br/>");
	}
	else
	{
		l->setText(l->text() + "FD failed!<br/>");
	}
	
	connect(&sock, SIGNAL(readyRead()), this, SLOT(readMulticastPacket()));
}

void MulticastClass::readMulticastPacket()
{
	QString OInMessage;
	QHostAddress PeerIp;

	while (sock.hasPendingDatagrams())
	{

	    QByteArray datagram;
	    datagram.resize(sock.pendingDatagramSize( ));
	    sock.readDatagram(datagram.data(), (qint64)datagram.size(), &PeerIp, &port);
	    OInMessage = datagram.data();
	    l->setText(l->text() + "msg: '" + OInMessage + "' peer ip: " + PeerIp.toString() + "<br />");

	}
}

